/**
 * @brief 数据中心头文件
 * @note
 * @par 示例
 * @code
 * user A:
    init:
        MDCClientHandle a_handle = MDataCenterLogin("a_obj");
    fini:
        MDataCenterLogout(a_handle);
    send msg:
        MDataCenterMsg *msg = MDataCenterCreateMsg(content_size);

        MDataCenterSendMsg("b_obj", msg);
   user B:
    init:
        MDCClientHandle b_handle = MDataCenterLogin("b_obj");
    fini:
        MDataCenterLogout(b_handle);
    recv msg:
        MDataCenterMsg *msg = MDataCenterPopMsg(b_handle);
        if (msg != NULL)
        {
            // deal this msg
            MDataCenterDestroyMsg(msg);
        }
 * @endcode utf-8
 */
#ifndef _M_DATA_CENTER_H_
#define _M_DATA_CENTER_H_
#include "m_types.h"
#include "m_errno.h"
#include "m_data_center_msg_define.h"

typedef void* MDCClientHandle;


#pragma pack(push, 1)
/**
 * MDataCenterMsg 数据中心交互消息结构体
 */
typedef struct MDataCenterMsgTag
{
    UInt16 msg_type;     // 消息类型，详见 MDataCenterMsgType
    UInt16 content_len;  // 附加内容长度
    UInt8  content[0];   // 附加内容
} MDataCenterMsg;
#pragma pack(pop)

/**
 * @brief 注册客户端
 *
 * @param client_name 客户端名称
 * @return 客户端句柄，NULL 则注册失败
 */
MDCClientHandle MDataCenterLogin(const Int8 *client_name);

/**
 * @brief 注销客户端
 *
 * @param client_handle 客户端句柄
 * @return 执行结果，详见 MErrCode
 */
Int32 MDataCenterLogout(MDCClientHandle client_handle);

/**
 * @brief 创建交互消息，内含内存申请
 *
 * @param content_size 附加内存长度
 * @return MDataCenterMsg* 返回的消息，为NULL则内存申请失败
 */
MDataCenterMsg* MDataCenterCreateMsg(UInt16 content_size);

/**
 * @brief 销毁交互消息，内含内存释放
 *
 * @param msg_t 待销毁消息结构体
 */
void MDataCenterDestroyMsg(MDataCenterMsg *msg_t);

/**
 * @brief 发送交互消息，需先创建
 *
 * @param recviver_name 接收者名称，详见 MDataCenterUser
 * @param msg_t 待发送消息结构体，由 MDataCenterCreateMsg 创建
 * @return 执行结果，详见 MErrCode
 */
Int32 MDataCenterSendMsg(const Int8 *recviver_name, MDataCenterMsg *msg_t);

/**
 * @brief 获取交互消息，但不取出，禁止调用接口摧毁消息
 *
 * @param client_handle 客户端句柄
 * @return MDataCenterMsg* NULL 表示没有消息，否则返回消息结构体
 */
MDataCenterMsg* MDataCenterPeekMsg(MDCClientHandle client_handle);

/**
 * @brief 获取交互消息，并取出，需调用接口摧毁消息
 *
 * @param client_handle 客户端句柄
 * @return MDataCenterMsg* NULL 表示没有消息，否则返回消息结构体
 */
MDataCenterMsg* MDataCenterPopMsg(MDCClientHandle client_handle);


#endif  // _M_DATA_CENTER_H_
